今天我想延續第九天學過的RecyclerView,那時只是一個最基本的應用。,RecyclerView 還有許多進階的應用場景,例如:
今天,我們就要來解決這兩個問題。
RecyclerView 項目點擊事件我們會在 Adapter 裡新增一個「監聽器」介面,並讓 MainActivity 來實現這個介面,這樣就能在 MainActivity 中處理點擊事件。
在 YourAdapter.java 中新增介面:
在你的 Adapter 類別裡,新增一個 interface。
`// 在 Adapter 類別裡面
public class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {
// 定義一個介面,用來處理點擊事件
public interface OnItemClickListener {
void onItemClick(int position);
}
private OnItemClickListener listener;
// 新增一個方法,用來設定監聽器
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
// ... 其他程式碼 ...
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
// ... 綁定資料的程式碼 ...
holder.itemView.setOnClickListener(v -> {
if (listener != null) {
listener.onItemClick(position);
}
});
}
}`
在 MainActivity.java 中實現介面並設定監聽器:
`import android.widget.Toast;
// 讓你的 MainActivity 實現你的介面
public class MainActivity extends AppCompatActivity implements YourAdapter.OnItemClickListener {
// ... 其他程式碼 ...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... 初始化 RecyclerView 和 Adapter ...
yourAdapter.setOnItemClickListener(this);
}
// 實現介面的方法
@Override
public void onItemClick(int position) {
// 在這裡處理點擊事件
String clickedItem = yourDataList.get(position);
Toast.makeText(this, "點擊了: " + clickedItem, Toast.LENGTH_SHORT).show();
}
}`
程式碼解釋:
- 我們在 Adapter 中定義了一個 interface,這就像是訂立了一個「契約」。
- onBindViewHolder 中,我們為每個項目設定了一個 OnClickListener。當項目被點擊時,它就會呼叫 listener.onItemClick()。
- MainActivity 實現了這個「契約」,並在 onCreate 中將自己設定為 listener,這樣當點擊事件發生時,onItemClick() 方法就會被呼叫。
RecyclerView 預設只能處理一種項目佈局。但我們可以透過覆寫 Adapter 的兩個方法,來告訴 RecyclerView:「這個位置的項目,請用這種佈局。」YourAdapter.java 中覆寫方法:
`public class YourAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
// ... 其他程式碼 ...
private static final int TYPE_TEXT = 0; // 第一種項目類型
private static final int TYPE_IMAGE = 1; // 第二種項目類型
@Override
public int getItemViewType(int position) {
// 在這裡判斷這個位置的項目是哪種類型
if (dataList.get(position).isText()) { // 假設你的資料類別有一個判斷方法
return TYPE_TEXT;
} else {
return TYPE_IMAGE;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 根據 viewType 決定要載入哪種佈局
if (viewType == TYPE_TEXT) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_text, parent, false);
return new TextViewHolder(view); // 建立對應的 ViewHolder
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_image, parent, false);
return new ImageViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
// 根據 ViewHolder 的類型來綁定資料
if (holder instanceof TextViewHolder) {
// 綁定文字資料
} else if (holder instanceof ImageViewHolder) {
// 綁定圖片資料
}
}
}`
程式碼解釋:
- getItemViewType():這是最關鍵的方法。它會告訴 RecyclerView,position 這個位置的項目,屬於哪種類型(TYPE_TEXT 或 TYPE_IMAGE)。
- onCreateViewHolder():RecyclerView 會根據 getItemViewType() 回傳的類型,來呼叫這個方法,並傳入 viewType。我們就可以根據這個 viewType,載入不同的佈局。
今天我們學會了 RecyclerView 的兩個進階應用:
Adapter 中新增 interface 來處理項目點擊事件。getItemViewType() 和 onCreateViewHolder(),讓 RecyclerView 能夠顯示多種不同樣式的項目。明天見!